package jp.nyatla.tap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import jp.nyatla.nsdb.NyatlaTwitterGatewayException;
import twitter4j.*;
import twitter4j.http.AccessToken;
import twitter4j.http.RequestToken;

import java.util.*;
import java.util.logging.Logger;

public abstract class TwitterSession
{
	private Twitter _connected_twitter=null;
	public HttpSession _session;
	protected HttpServletRequest _ref_request;
	protected TwitterSessionData _session_data;
	protected abstract void setOAuthConsumer(Twitter i_t);

	
	public TwitterSession(final HttpServletRequest i_req,boolean is_commit)throws TwitterException
	{
		this._ref_request=i_req;
		this._session = i_req.getSession();
		TwitterSessionData d = (TwitterSessionData) this._session.getAttribute("TwitterSession");
		if (d == null) {
			d = new TwitterSessionData(i_req.getHeader("user-agent"));
			this._session.setAttribute("TwitterSession", d);
		}
		d.c++;
		switch (d.state) {
		case TwitterSessionData.ST_PREV:
			try{
				Twitter twitter = new TwitterFactory().getInstance();
				this.setOAuthConsumer(twitter);
				//サインイン状態にセット
				d.initSignin(twitter);
			}catch(Exception e){
				d.initSignOut();
				Logger log = Logger.getLogger(this.getClass().getName());
				log.info("TwitterSession->ST_PREV\n"+e.toString());
			}
			break;
		case TwitterSessionData.ST_SIGNIN:
			break;
		default:// self::ST_UNKNOWN:
			break;
		}
		//commit
		this._session_data=d;
		if(is_commit){
			this.commitSession();
		}
	}

	private String _authentication_url = null;

	public String getAuthenticationURL(String i_callback_uri,boolean is_commit)
			throws TwitterException, NyatlaTwitterGatewayException {
		TwitterSessionData d = this._session_data;
		if (d.state == TwitterSessionData.ST_SIGNIN) {
			throw new NyatlaTwitterGatewayException();
		}
		if (this._authentication_url != null) {
			return this._authentication_url;
		}
		Twitter twitter = new TwitterFactory().getInstance();
		this.setOAuthConsumer(twitter);
		RequestToken requestToken = twitter.getOAuthRequestToken(i_callback_uri);
		d.initPrev(requestToken);
		this._authentication_url = requestToken.getAuthenticationURL();
		//commit
		if(is_commit){
			this.commitSession();
		}
		return this._authentication_url;
	}
	public int getStateVal(){
		return this._session_data.state;
	}
	public boolean isSignIn() {
		return this._session_data.state == TwitterSessionData.ST_SIGNIN;
	}
	/**
	 * ツイッターセッションのデータを得る。
	 * @return
	 */
	public TwitterSessionData refSessionData()
	{
		return this._session_data;
	}
	public int getClientType()
	{
		return this._session_data.client_type;
	}
	/**
	 * サインアウトする。
	 */
	public void signOut()
	{
		this._session_data.initSignOut();
		this._session.setAttribute("TwitterSession",this._session_data);
	}
	/**
	 * サインイン済みのツイッターコネクションを得る
	 * @return
	 * @throws NyatlaTwitterGatewayException
	 */
	public Twitter getConnection() throws NyatlaTwitterGatewayException
	{
		TwitterSessionData d = this._session_data;
		if (d.state != TwitterSessionData.ST_SIGNIN) {
			throw new NyatlaTwitterGatewayException();
		}
		if(this._connected_twitter==null){
			Twitter twitter = new TwitterFactory().getInstance();
			this.setOAuthConsumer(twitter);
			twitter.setOAuthAccessToken(new AccessToken(d.access_token,d.access_token_secret));
			this._connected_twitter=twitter;
		}
		return this._connected_twitter;
	}
	public void commitSession()
	{
		this._session.setAttribute("TwitterSession",this._session_data);
	}
	public HttpServletRequest refReq()
	{
		return this._ref_request;
	}	
	public void setLastId(long i_last_id,boolean is_commit)
	{
		this._session_data.last_status_id=i_last_id;
		if(is_commit){
			this.commitSession();
		}		
	}
	public boolean isMode(int i_arg)
	{
		return this._session_data.mode==i_arg;
	}
	public void setMode(int i_arg,boolean is_commit)
	{
		this._session_data.mode=i_arg;
		if(is_commit){
			this.commitSession();
		}
	}
	class BattleManager
	{
	}
}